<template>
  <div class="custom-time-axis">
    <!-- 时间轴刻度线 -->
    <div class="time-axis-scale">
      <div
        v-for="(minute, index) in minutesInDay"
        :key="index"
        :class="{ 'major-scale': minute % 60 === 0 }"
        :style="{ left: `${(minute / 1440) * 100}%` }">
        <span v-if="minute % 60 === 0">{{ formatHour(minute) }}</span>
      </div>
    </div>
    <!-- 滑块 -->
    <div class="time-axis-sliders">
      <div
        class="slider left-slider"
        :style="{ left: `${(leftTime / 1440) * 100}%` }"
        @mousedown="startDrag(SliderEnum.Left)">
        <span>{{ formatTime(leftTime) }}</span>
      </div>
      <div
        class="slider right-slider"
        :style="{ left: `${(rightTime / 1440) * 100}%` }"
        @mousedown="startDrag(SliderEnum.Right)">
        <span>{{ formatTime(rightTime) }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const emits = defineEmits(['on-timeChange']);

const SliderEnum = {
  /** 左滑块 */
  Left: 'left',
  /** 右滑块 */
  Right: 'right',
}

// 创建一个包含 145 个元素的数组，每个元素代表一天内的分钟数，间隔为 10 分钟
const minutesInDay = Array.from({ length: 145 }, (_, i) => i * 10);

const leftTime = ref(0);
const rightTime = ref(1440);

/** 是否拖动过程中 */
let isDragging = false;

/** 当前触发的滑块 */
let activeSlider = '';

/**
 * 格式化小时展示文本
 * @param minutes 
 */
const formatHour = (minutes) => {
  const hour = Math.floor(minutes / 60);
  return `${hour.toString().padStart(2, '0')}`;
};

const formatTime = (minutes) => {
  const hour = Math.floor(minutes / 60);
  const minute = minutes % 60;
  return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
};

/**
 * 触发滑块拖动事件
 * @param slider 
 */
const startDrag = (slider) => {
  isDragging = true;
  activeSlider = slider;
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', handleMouseUp);
};

/**
 * 滑块拖动事件
 * @param event 
 */
const handleMouseMove = (event) => {
  if (!isDragging) return;

  const container = document.querySelector('.custom-time-axis');
  if (!container) return;

  const rect = container.getBoundingClientRect();
  // 计算出鼠标指针相对于时间轴容器左边缘的水平偏移量
  const x = event.clientX - rect.left;
  // 鼠标指针在时间轴容器内的水平位置的百分比
  const percentage = (x / rect.width) * 100;
  // 一天总共有 1440 分钟（24 小时 × 60 分钟/小时），将这个比例乘以 1440，得到鼠标指针在时间轴上对应的分钟数
  const newTime = Math.round((percentage / 100) * 1440);

  if (activeSlider === SliderEnum.Left) {
    // 保证左滑块在右滑块左侧不超过5分钟
    leftTime.value = Math.min(newTime, rightTime.value - 5);
    leftTime.value = Math.max(leftTime.value, 0); // 添加左滑块最小时间限制
  } else {
    rightTime.value = Math.max(newTime, leftTime.value + 5);
    rightTime.value = Math.min(rightTime.value, 1440); // 添加右滑块最大时间限制
  }
  
  // 将结果发送给父组件
  emits('on-timeChange', {
    left: formatTime(leftTime.value),
    right: formatTime(rightTime.value),
  });
};

/**
 * 鼠标拖动滑块释放事件
 */
const handleMouseUp = () => {
  isDragging = false;
  activeSlider = null;
  document.removeEventListener('mousemove', handleMouseMove);
  document.removeEventListener('mouseup', handleMouseUp);
};

onMounted(() => {
  document.addEventListener('mouseup', handleMouseUp);
});

onUnmounted(() => {
  document.removeEventListener('mouseup', handleMouseUp);
  document.removeEventListener('mousemove', handleMouseMove)
});
</script>

<style scoped lang="less">
.custom-time-axis {
  position: relative;
  height: 100px;
  margin: 40px;
  user-select: none;

  .time-axis-scale {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 50px;
  border-bottom: 1px solid #ccc;

  .major-scale {
  height: 20px !important;
}

.major-scale > span {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
}
}

.time-axis-scale > div {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 10px;
  background-color: #ccc;
}

.time-axis-sliders {
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  height: 50px;

  .slider {
  position: absolute;
  top: 0;
  width: 10px;
  height: 30px;
  background-color: #a8abb2;
  cursor: grab;
  border-radius: 4px;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
}

.slider > span {
  position: absolute;
  top: 30px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  white-space: nowrap;
}
}
}


</style>